#define THIS_FILE "helmetcam.sqf"
#include <tmf_constants.h>
#include <tmf_macros.h>

#define HCAM_UI_DISP (uiNamespace getVariable "hcam_ui_disp")
#define HCAM_CTRL_PIP (uiNamespace getVariable "hcam_ctrl_pip")
#define HCAM_CTRL_TITLE (uiNamespace getVariable "hcam_ctrl_title")
#define HCAM_CTRL_BACK (uiNamespace getVariable "hcam_ctrl_back")
#define HCAM_CTRL_FRONT (uiNamespace getVariable "hcam_ctrl_front")

private ["_old","_neck","_pilot","_target","_camOn","_units","_pos1","_pos2","_vx1","_vy1","_vz1","_dir","_tilt","_dive","_tz","_veh"];

if (hcam_active || {isDedicated}) exitWith {};

// Init
_old = "";

// Create proxies
_neck = "Sign_Sphere10cm_F" createVehicleLocal position player;
_pilot = "Sign_Sphere10cm_F" createVehicleLocal position player;
_target = "Sign_Sphere10cm_F" createVehicleLocal position player;
hideObject _neck; 
hideObject _pilot; 
hideObject _target; 
_target attachTo [_neck,[0.5,10,0]];

// Create camera ->todo
//[player,_target,player,0] call BIS_fnc_liveFeed;
hcam_cam = "camera" camCreate getPos (vehicle player);
// TYRGHEN added an extra check when ending the cam script.
waitUntil {!isnil "hcam_cam" && {hcam_cam != ObjNull}};
808 cutRsc ["RscHcamDialog", "PLAIN"];
//systemChat "cam ready";
HCAM_CTRL_PIP ctrlsettext "#(argb,256,256,1)r2t(rendertarget0,1.0)";

// Remember zoomed state
if (hcam_zoom == 0) then {
	HCAM_CTRL_BACK ctrlSetPosition [0.85*safezoneW+safezoneX, 0.725*safezoneH+safezoneY,0.15*safezoneW,0.11*safezoneH];
	HCAM_CTRL_PIP ctrlSetPosition [0.8635*safezoneW+safezoneX, 0.733*safezoneH+safezoneY,0.122*safezoneW,0.095*safezoneH];
	HCAM_CTRL_TITLE ctrlSetPosition [0.8635*safezoneW+safezoneX, 0.81*safezoneH+safezoneY,0.122*safezoneW,0.015*safezoneH];
	HCAM_CTRL_FRONT ctrlSetPosition [0.8635*safezoneW+safezoneX, 0.733*safezoneH+safezoneY,0.122*safezoneW,0.095*safezoneH];
	
	HCAM_CTRL_BACK ctrlCommit 0;
	HCAM_CTRL_PIP ctrlCommit 0;
	HCAM_CTRL_TITLE ctrlCommit 0;
	HCAM_CTRL_FRONT ctrlCommit 0;
};

// adjust Camera offset & settings
hcam_offset = [-0.18,0.08,0.05];
hcam_cam attachTo [_neck,hcam_offset]; // ->todo: grab this from a custom config
hcam_cam camSetFov 0.6;
hcam_cam camSetTarget _target;
hcam_cam camCommit 2; // commit Changes

hcam_night = sunOrMoon == 0;
// add color correction
if (hcam_night) then {
	"rendertarget0" setPiPEffect [1];
} else {
	"rendertarget0" setPiPEffect [3, 1, 0.8, 1, 0.1, [0.3, 0.3, 0.3, -0.1], [1.0, 0.0, 1.0, 1.0], [0, 0, 0, 0]];
};
// Ready!
hcam_active = true;
_camOn = false;

// start cam-update loop
// TYRGHEN added an extra check when ending the cam script.
while {!isnil "hcam_cam" && {hcam_cam != ObjNull} && {isPipEnabled}} do {	
	// destroy camera and cancel the loop if player closes the liveFeed or takes off his tactical glasses.
	// TYRGHEN
	if !((goggles player) in hcam_goggles && alive player && !dialog) then {
		hcam_cam cameraEffect ["TERMINATE", "BACK"];
		_camOn = false;
		camDestroy hcam_cam;
		hcam_cam = nil;
	} else {
		// Fetch list of units
		if (hcam_units == "group") then {
		  _units = units (group player);
		} else {
		  _units = hcam_units;
		};
		
		// Set Target
		// TYRGHEN - Added a fallback check to default on the player
		if (count _units > hcam_id) then {
			hcam_target = _units select hcam_id;
		} else {
			hcam_target = player;
		};
		//HCAM_CTRL_TITLE ctrlSetText name hcam_target;
		
		// TYRGHEN - added test for valid hcam_target
		if (!isnil "hcam_target" && {!isnull hcam_target}) then {
			// check if the camtarget has changed and update the camera
			if (name hcam_target != _old) then {
				_neck attachTo [hcam_target,[0,0,0],"neck"];
				_pilot attachTo [hcam_target,[0,0,0],"pilot"];
				_old = name hcam_target;
				hcam_cam cameraEffect ["INTERNAL", "BACK","rendertarget0"];
				HCAM_CTRL_TITLE ctrlsettext (name hcam_target);
			};

			// check if camtarget has suitable headgear
			if (((headgear hcam_target) in hcam_headgear) || (count hcam_headgear <= 0)) then {
				if (!_camOn) then {
					// Valid headgear -> Re-enable the camera
					hcam_cam cameraEffect ["INTERNAL", "BACK","rendertarget0"];
					hcam_night = sunOrMoon == 0;
					if (hcam_night) then {
						"rendertarget0" setPiPEffect [1];
					} else {
						"rendertarget0" setPiPEffect [3, 1, 0.8, 1, 0.1, [0.3, 0.3, 0.3, -0.1], [1.0, 0.0, 1.0, 1.0], [0, 0, 0, 0]];
					};
					HCAM_CTRL_PIP ctrlsettext "#(argb,256,256,1)r2t(rendertarget0,1.0)";
					_camOn = true;
				} else {
					if !(hcam_night && (sunOrMoon == 0)) then {
						hcam_night = sunOrMoon == 0;
						if (hcam_night) then {
							"rendertarget0" setPiPEffect [1];
						} else {
							"rendertarget0" setPiPEffect [3, 1, 0.8, 1, 0.1, [0.3, 0.3, 0.3, -0.1], [1.0, 0.0, 1.0, 1.0], [0, 0, 0, 0]];
						};
					};
				};
			} else {
				if (_camOn) then {
					// No valid headgear -> Black screen
					hcam_cam cameraEffect ["TERMINATE", "BACK"];
					_camOn = false;
				};
			};
		} else {
			if (_camOn) then {
				// No valid headgear -> Black screen
				hcam_cam cameraEffect ["TERMINATE", "BACK"];
				_camOn = false;
			};
		};

    
		if (_camOn) then {
			_veh = vehicle hcam_target;

			// check if camtarget is inside vehicle
			if (hcam_target != _veh) then {
				// Attach cam to vehicle
				_mempoints = getArray ( configfile/"CfgVehicles"/typeOf _veh/"memoryPointDriverOptics" );
				if (count _mempoints > 0) then {
					TRACE_1("_mempoints","_mempoints");
					hcam_cam attachTo [_veh,[0,0,0], _mempoints select 0];
					_target attachTo [_veh,[0,1,0], _mempoints select 0];
				} else {
					hcam_cam attachTo [_veh,[0,1.5,0]];
					_target attachTo [_veh,[0,2.5,0]];
				};
			} else {
				// Recalculate headposition of camtarget
				_pos1 = hcam_target worldToModel getPos _pilot;
				_pos2 = hcam_target worldToModel getPos _neck;

				_vx1 = (_pos1 select 0) - (_pos2 select 0);
				_vy1 = (_pos1 select 1) - (_pos2 select 1);
				_vz1 = (_pos1 select 2) - (_pos2 select 2);
				_dir = (_vx1 atan2 _vy1) - 25;
				// _tilt = (_vz1 atan2 _vx1) - 56.6;
				_dive = (_vy1 atan2 _vz1) + 35; 
		  
				if ((sin _dive) == 0) then {INC(_dive)};
				_tz = ((1 / sin _dive) * cos _dive); 	

				// Update cameraposition
				hcam_cam attachTo [_neck,hcam_offset];
				_target attachTo [_neck,[0.5,10,_tz*10]];
				_neck setDir _dir;
		  
				sleep 0.1;
			};
		} else {
			sleep 1;
		};
	};
};

// loop ended, cleanup
808 cutFadeOut 0;
hcam_active = false;
deleteVehicle _neck;
deleteVehicle _pilot;
deleteVehicle _target;